package com.king.common.utils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.king.framework.base.domain.vo.LoginUser;
import com.king.framework.base.domain.vo.TableSupport;

/**
 * 查询公用类
 * @author lenovo
 *
 */
public class SearchUtils<T> {
	
	/**
	 * BW 以什么开始 begin with, EW 以什么结尾 end with
	 * @author yy-team
	 * @date 2022年2月25日
	 */
	public enum Operator {
		EQ("equal"), LIKE("like"), LLIKE("like"), RLIKE("like"), NOTLIKE("not-like"), GT("greater-than"), LT("less-than"), GTE("greater-than-or-equal-to"), LTE(
				"less-than-or-equal-to"), NULL("is-null"), NOTNULL("is-not-null"),  NE("not-equal"), IN("in"), NOTIN("not-in"), BT("between"),;

		private final String desc;

		public String getDesc() {
			return desc;
		}

		private Operator(String desc) {
			this.desc = desc;
		}

	}
	
	@SuppressWarnings("rawtypes")
	public static QueryWrapper buildQueryWrapper(){
		QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
		LoginUser user = SecurityUtils.getLoginUser();
		if(user != null && !user.isAdmin()){
			queryWrapper.eq("groupid", user.getGroupid());
		}
		return queryWrapper;
	}

	@SuppressWarnings("rawtypes")
	public static QueryWrapper buildQueryWrapper(Map<String, Object> searchMap){
		QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
//		LoginUser user = SecurityUtils.getLoginUser();
//		if(!SysUser.isAdmin(user.getUserId())&& user != null){
//			queryWrapper.eq("groupid", user.getGroupid());
//		}
        if (searchMap != null) {
        	parseQueryWrapper(queryWrapper, searchMap);
        }
		return queryWrapper;
	}
	
	public static UpdateWrapper buildUpdateWrapper() {
		UpdateWrapper<Object> updateWrapper = new UpdateWrapper<>();
		LoginUser user = SecurityUtils.getLoginUser();
		if(user != null && !user.isAdmin()){
			updateWrapper.eq("groupid", user.getGroupid());
		}
		return updateWrapper;
	}
	
	
	
	private static void parseQueryWrapper(QueryWrapper<?> queryWrapper,Map<String, Object> searchParams) {
		for (Entry<String, Object> entry : searchParams.entrySet()) {
			// 过滤掉空值
			String key = entry.getKey();
			// 某些Key不是查询条件
			if (key.equals(TableSupport.PAGE_NUM) || 
					key.equals(TableSupport.PAGE_SIZE)) {
				continue;
			}

			Object val = entry.getValue();
			if (val == null) {
				continue;
			}
			
			if(key.equals(TableSupport.ORDER_BY_COLUMN)&&StringUtils.isNotEmpty(val.toString())){
				String []sortsArr = val.toString().split(TableSupport.ORDER_SPLIT);
				queryWrapper.orderBy(sortsArr.length == 2, sortsArr[1].equals("asc"), sortsArr[0]);
				continue;
			}

//			key = replaceKey(key);
			// 拆分operator与filedAttribute
			String[] names = StringUtils.split(key, "_");

			if (names.length ==1 ) {
				if (val instanceof String) {
					// 字符串默认使用like
					key = "LIKE_" + key;
				} else {
					key = "EQ_" + key;
				}
				names = StringUtils.split(key, "_");
			}

			String column = key.substring(key.indexOf("_") + 1, key.length());// 避免查询条件的字段 有下划线 ，如 // search_LIKE_job_number
			
			//转下划线
			column = underline(new StringBuffer(column)).toString();

			Operator operator = Operator.valueOf(names[0]);

			if (operator != Operator.NULL && operator != Operator.NOTNULL) {
				if (val instanceof String && StringUtils.isBlank(String.valueOf(val))) {
					continue;
				}
			}
			switch (operator) {
            	case EQ:
            		queryWrapper.eq(column, val);
            		break;
                case LIKE:
                	queryWrapper.like(column, val);
                    break;
                case LLIKE:
                	queryWrapper.likeLeft(column, val);
                    break;
                case RLIKE:
                	queryWrapper.likeRight(column, val);
                    break;
                case NOTLIKE:
                	queryWrapper.notLike(column, val);
                    break;	
                case GT:
                    queryWrapper.gt(column, val);
                    break;
                case LT:
                    queryWrapper.lt(column, val);
                    break;
                case GTE:
                    queryWrapper.ge(column, val);
                    break;
                case LTE:
                    queryWrapper.le(column, val);
                    break;
                case NOTNULL:
                    queryWrapper.isNotNull(column);
                    break;
                case NULL:
                    queryWrapper.isNull(column);
                    break;
                case NE:
                    queryWrapper.ne(column, val);
                    break;
                case IN:
                	List<String> inValues = Arrays.stream(((String) val).split(",")).map(s -> s.trim()).collect(Collectors.toList());
                	queryWrapper.in(column, inValues);
                    break;
                case NOTIN:
                	List<String> notInValues = Arrays.stream(((String) val).split(",")).map(s -> s.trim()).collect(Collectors.toList());
                	queryWrapper.notIn(column, notInValues);
                    break;
                case BT:
                    String[] btValues = ((String) val).split(",");
                    queryWrapper.between(column, btValues[0], btValues[1]);
                    break;
                default:
                	queryWrapper.like(column, val);
                    break;
			} 	
		}
	}

	public static StringBuffer underline(StringBuffer str) {
		Pattern pattern = Pattern.compile("[A-Z]");
		Matcher matcher = pattern.matcher(str);
		StringBuffer sb = new StringBuffer(str);
		if (matcher.find()) {
			sb = new StringBuffer();
			// 将当前匹配子串替换为指定字符串，并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个StringBuffer对象里。
			// 正则之前的字符和被替换的字符
			matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
			// 把之后的也添加到StringBuffer对象里
			matcher.appendTail(sb);
		} else {
			return sb;
		}
		return underline(sb);
	}


}
